package com.tms.ned.controlmonitor.adapters;

import java.awt.Component;

import com.tms.ned.controlmonitor.ComponentChangeListener;
import com.tms.ned.controlmonitor.decorators.ComponentDecorator;
import com.tms.ned.controlmonitor.validate.ValidationStatus;
import com.tms.ned.controlmonitor.validate.Validator;

/*
 * Licensed under the Apache License, Version 2.0;<br> 
 * 
 * You may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless 
 * required by applicable law or agreed to in writing, software distributed under the License 
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and limitations under the License. 
 */

/**
 * Adapts a UI component to throw ComponentChangeEvents. Each adapted component
 * will also track the initial and current "values" of the component.
 *
 * The adapter will also provide for validation of the component, and it will
 * use a ComponentDecorator instance to decorate the adapted component when its
 * validation status changes.
 *
 * @author bshannon
 *
 */
public interface ComponentAdapter {

	/**
	 * Adds a change listener to the component adapter.
	 *
	 * @param c
	 *            the listener
	 */
	public void addChangeListener(ComponentChangeListener c);

	/**
	 * Removes the given change listener from the component adapter.
	 *
	 * @param c
	 *            the listener
	 */
	public void removeChangeListener(ComponentChangeListener c);

	/**
	 *
	 * @return the initial value the component the component had.
	 */
	public Object getInitialValue();

	/**
	 * Sets the initial value of the component. Implementers of this method
	 * should probably throw a ComponentChangeEvent to notify listeners of this
	 * change.
	 *
	 * @param o
	 */
	public void setInitialValue(Object o);

	/**
	 *
	 * @return the current value of the component. The value might be
	 *         "remembered" by the last change event, or gleamed from the
	 *         underlying component on the fly. The only rule is that the return
	 *         value of this class represents in some way the current 'value' of
	 *         the component. Feel free to implement this as a hash code or some
	 *         other smaller representation of a component, it's only important
	 *         that this value represents a change from getInitialValue() when
	 *         the new value is different and that it represents the same value
	 *         of getInitialValue() when the value of the component is the same
	 *         (or 'clean').
	 */
	public Object getCurrentValue();

	/**
	 *
	 * @return the component that is being adapted.
	 */
	public Component getComponent();

	/**
	 *
	 * @return the name of the component. Useful for debugging or info purposes.
	 */
	public String getName();

	/**
	 *
	 * @return True if the component's initial value doesn't match the current
	 *         value. When the value of getInitialValue() is different than that
	 *         returned from "getCurrentValue()", then this method must return
	 *         "TRUE".
	 */
	public boolean isDirty();

	/**
	 * Shortcut to check the currentValidationStutus's validity. Must return
	 * TRUE when the ValidationStatus from getCurrentValidationStatus() is
	 * VALID.
	 *
	 * @return
	 */
	public boolean isValid();

	/**
	 *
	 * @return the ComponentDecorator used to decorate the component when its
	 *         validation status changes.
	 */
	public ComponentDecorator getComponentDecorator();

	/**
	 * Validates the component, after which the getCurrentValidationStatus()
	 * method will provide the results of the validation. Calling
	 * getCurrentValidationStatus() before this method is ultimately called is
	 * undefined.
	 */
	public void validate();

	/**
	 * After calling validate, this method provides the CURRENT validation
	 * status of the adapted component. By default, this returns
	 * ValidationStatus.VALID.
	 *
	 * @return The current validation status of the adapted component.
	 */
	public ValidationStatus getCurrentValidationStatus();

	/**
	 * Sets a new validator onto this component adapter.
	 *
	 * @param validator
	 *            The new Validator class to use to validate the component.
	 */
	public void setValidator(Validator validator);
}
